package com.mjk.common.core.health;

import org.apache.http.StatusLine;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.json.JsonParser;
import org.springframework.boot.json.JsonParserFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StreamUtils;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;

@Configuration
@ConditionalOnProperty(value="plumelog.es.esHosts",havingValue = "true",matchIfMissing = false)
public class ElasticsearchHealthIndicator extends AbstractHealthIndicator {
    private static final String RED_STATUS = "red";
    private final RestClient client;
    private final JsonParser jsonParser;

    public ElasticsearchHealthIndicator(RestClient client) {
        super("Elasticsearch health check failed");
        this.client = client;
        this.jsonParser = JsonParserFactory.getJsonParser();
    }

    protected void doHealthCheck(Health.Builder builder) throws Exception {
        Response response = this.client.performRequest(new Request("GET", "/_cluster/health/"));
        StatusLine statusLine = response.getStatusLine();
        if (statusLine.getStatusCode() != 200) {
            builder.down();
            builder.withDetail("statusCode", statusLine.getStatusCode());
            builder.withDetail("reasonPhrase", statusLine.getReasonPhrase());
        } else {
            InputStream inputStream = response.getEntity().getContent();

            try {
                this.doHealthCheck(builder, StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8));
            } catch (Throwable var8) {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (Throwable var7) {
                        var8.addSuppressed(var7);
                    }
                }

                throw var8;
            }

            if (inputStream != null) {
                inputStream.close();
            }

        }
    }

    private void doHealthCheck(Health.Builder builder, String json) {
        Map<String, Object> response = this.jsonParser.parseMap(json);
        String status = (String)response.get("status");
        if ("red".equals(status)) {
            builder.outOfService();
        } else {
            builder.up();
        }

        builder.withDetails(response);
    }
}
